using System;
namespace Reminder
{
    public class Reminder
    {
        public static readonly Reminder Empty = new Reminder(TimeSpan.Zero);

        TimeSpan Duration { get; set; }
        DateTime StartTime { get; set; }
        DateTime EndTime { get; set; }

        public string Name { get; private set; }
        public string Message { get; private set; }
        public TimeSpan TimeFromNow { get { return (HasStarted) ? EndTime - DateTime.Now : TimeSpan.MaxValue; } }

        public bool HasStarted { get { return StartTime != DateTime.MinValue && StartTime <= DateTime.Now; } }
        public bool HasExpired { get { return HasStarted & EndTime <= DateTime.Now; } }

        internal Reminder(TimeSpan duration) : this(string.Empty, duration) { }

        internal Reminder(string message, TimeSpan duration) : this(string.Empty, message, duration) { }

        internal Reminder(string name, string message, TimeSpan duration)
        {
            this.Duration = duration;
            this.Name = name;
            this.Message = message;

            StartTime = EndTime = DateTime.MinValue;
        }

        public void StartNow()
        {
            StartAt(DateTime.Now);
        }

        public void StartAt(DateTime datetime)
        {
            StartTime = datetime;
            EndTime = StartTime + Duration;
        }

        public bool Equals(Reminder other)
        {
            return Reminder.Equals(this, other);
        }

        public override bool Equals(object obj)
        {
            return Reminder.Equals(this, obj as Reminder);
        }

        private static bool Equals(Reminder reminder1, Reminder reminder2)
        {
            if (Object.Equals(null, reminder1) || Object.Equals(null, reminder2)
                || reminder1.GetType() != reminder2.GetType())
                return false;
            if (Object.ReferenceEquals(reminder1, reminder2)) return true;

            return reminder1.Message == reminder2.Message
                && reminder1.EndTime == reminder2.EndTime
                && reminder1.Name == reminder2.Name;
        }

        public override int GetHashCode()
        {
            var hash = EndTime.GetHashCode();
            hash ^= Duration.GetHashCode();
            if (Message != null)
                hash ^= Message.GetHashCode();
            if (Name != null)
                hash ^= Name.GetHashCode();
            return hash;
        }
    }
}